home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 February: Tool Chest / Dev.CD Feb 94.toast / Tool Chest / Development Platforms / AppsToGo / AppsToGo.src / DTS.Lib / Init.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-18  |  9.0 KB  |  274 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** Program:         DTS.Lib
  5. ** File:            init.c
  6. ** Some code from:  Traffic Light 2.0 (2.0 version by Keith Rollin)
  7. ** Modified by:     Eric Soldan
  8. **
  9. ** Copyright © 1989-1991 Apple Computer, Inc.
  10. ** All rights reserved.
  11. */
  12.  
  13. /* You may incorporate this sample code into your applications without
  14. ** restriction, though the sample code has been provided "AS IS" and the
  15. ** responsibility for its operation is 100% yours.  However, what you are
  16. ** not permitted to do is to redistribute the source as "DSC Sample Code"
  17. ** after having made changes. If you're going to re-distribute the source,
  18. ** we require that you make it clear in the source that the code was
  19. ** descended from Apple Sample Code, but that you've made changes. */
  20.  
  21.  
  22.  
  23. /*****************************************************************************/
  24.  
  25.  
  26.  
  27. #include "DTS.Lib2.h"
  28. #include "DTS.Lib.protos.h"
  29.  
  30. #ifndef __ERRORS__
  31. #include <Errors.h>
  32. #endif
  33.  
  34. #ifndef __GESTALTEQU__
  35. #include <GestaltEqu.h>
  36. #endif
  37.  
  38.  
  39.  
  40. /*****************************************************************************/
  41.  
  42.  
  43.  
  44. /* Set up the whole world, including global variables, Toolbox managers, and
  45. ** menus.  We also create our one application window at this time.  Since
  46. ** window storage is non-relocateable, how and when to allocate space for
  47. ** windows is very important so that heap fragmentation does not occur. */
  48.  
  49. /* The code that used to be part of ForceEnvirons has been moved into this
  50. ** module.  If an error is detected, instead of merely doing an ExitToShell,
  51. ** which leaves the user without much to go on, we call DeathAlert, which puts
  52. ** up a simple alert that just says an error occurred and then calls
  53. ** ExitToShell.  Since there is no other cleanup needed at this point if an
  54. ** error is detected, this form of error-handling is acceptable.  If more
  55. ** sophisticated error recovery is needed, an exception mechanism, such as is
  56. ** provided by Signals, can be used. */
  57.  
  58.  
  59.  
  60. /*****************************************************************************/
  61.  
  62.  
  63.  
  64. /* NOTE:  The “g” prefix is used to emphasize that a variable is global. */
  65.  
  66. OSType    gDocCreator;
  67. Boolean    gQuitApplication;
  68.  
  69. short    gMenuBar   = rMenuBar;
  70. short    gAppleMenu = mApple;
  71.  
  72. extern Boolean        gHasAppleEvents, gNoDefaultDocument;
  73. extern RgnHandle    gCursorRgn;
  74. extern short        gPrintPage;
  75. extern OSType        gAppWindowType;
  76. extern TreeObjHndl    gWindowFormats;
  77.  
  78. typedef void (*callBack)(void);
  79.  
  80.  
  81.  
  82. /*****************************************************************************/
  83. /*****************************************************************************/
  84.  
  85.  
  86.  
  87. /* Given minHeap and minSpace values, get stuff going.  Also, we are passed
  88. ** in two procedure pointers.  If these are not nil, they are called at
  89. ** intermediate points during the initialization process.  The first proc
  90. ** is called after the Utilities.c standard initialization is complete.  The
  91. ** second proc is called very near the end of the initialization, but just
  92. ** prior to the menus being initialized. */
  93.  
  94. #pragma segment Initialize
  95. void    Initialize(short moreMasters, long minHeap, long minSpace, ProcPtr init1, ProcPtr init2)
  96. {
  97.     long    total, contig;
  98.  
  99.     StandardInitialization(moreMasters);
  100.  
  101.     if (init1)
  102.         (*(callBack)init1)();    /* Give app a chance to do some init stuff here. */
  103.  
  104.     /* Make sure that the machine has at least 128K ROMs.
  105.     ** If it doesn’t, exit. */
  106.  
  107.     if ((gMachineType < gestaltMac512KE) || (!gHasWaitNextEvent))
  108.         DeathAlert(rBadNewsStrings, sWimpyMachine);
  109.  
  110.     /* We used to make a check for memory at this point by examining
  111.     ** ApplLimit, ApplicZone, and StackSpace and comparing that to the minimum
  112.     ** size we told MultiFinder we needed.  This did not work well because it
  113.     ** assumed too much about the relationship between what we asked
  114.     ** MultiFinder for and what we would actually get back, as well as how to
  115.     ** measure it.  Instead, we will use an alternate method comprised of
  116.     ** two steps. */
  117.  
  118.     /* It is better to first check the size of the application heap against a
  119.     ** value that you have determined is the smallest heap the application can
  120.     ** reasonably work in.  This number should be derived by examining the
  121.     ** size of the heap that is actually provided by MultiFinder when the
  122.     ** minimum size requested is used.  The derivation of the minimum size
  123.     ** requested from MultiFinder is described in DTS.Lib.h.  The check should
  124.     ** be made because the preferred size can end up being set smaller than
  125.     ** the minimum size by the user.  This extra check acts to ensure that
  126.     ** your application is starting from a solid memory foundation. */
  127.  
  128.     if ((long)GetApplLimit() - (long)ApplicZone() < minHeap)
  129.         DeathAlert(rBadNewsStrings, sHeapTooSmall);
  130.  
  131.     /* Next, make sure that enough memory is free for your application to run.
  132.     ** It is possible for a situation to arise where the heap may have been of
  133.     ** required size, but a large scrap was loaded which left too little
  134.     ** memory.  To check for this, call PurgeSpace and compare the result with
  135.     ** a value that you have determined is the minimum amount of free memory
  136.     ** your application needs at initialization.  This number can be derived
  137.     ** several different ways.  One way that is fairly straightforward is to
  138.     ** run the application in the minimum size configuration as described
  139.     ** previously.  Call PurgeSpace at initialization and examine the value
  140.     ** returned.  However, you should make sure that this result is not being
  141.     ** modified by the scrap’s presence.  You can do that by calling ZeroScrap
  142.     ** before calling PurgeSpace.  Make sure to remove that call before
  143.     ** shipping, though. */
  144.  
  145.     PurgeSpace(&total, &contig);
  146.     if (total < minSpace)
  147.         DeathAlert(rBadNewsStrings, sNoFreeRoomInHeap);
  148.  
  149.     /* The extra benefit to waiting until after the Toolbox Managers have been
  150.     ** initialized to check memory is that we can now give the user an alert
  151.     ** to tell him/her what happened.  Although it is possible that the memory
  152.     ** situation could be worsened by displaying an alert, MultiFinder would
  153.     ** gracefully exit the application with an informative alert if memory
  154.     ** became critical.  Here we are acting more in a preventative manner to
  155.     ** avoid future disaster from low-memory problems. */
  156.  
  157.     if (init2)
  158.         (*(callBack)init2)();    /* Give app a chance to do some init stuff here. */
  159.  
  160.     gDocCreator = gSignature;
  161.         /* Copy the app creator type read by Utilities.c.  By copying it, the app can
  162.         ** change it if necessary to coerce various file I/O functions that use
  163.         ** gDocCreator to generate a file of a different creator type. */
  164.  
  165.     StandardMenuSetup(gMenuBar, gAppleMenu);
  166.  
  167.     qd.randSeed = TickCount();
  168. }
  169.  
  170.  
  171.  
  172. /*****************************************************************************/
  173.  
  174.  
  175.  
  176. /* This function handles the documents selected in the finder, either for
  177. ** loading or for printing.  This is only if we don't have AppleEvents.
  178. ** If we have AppleEvents, then this will all be done automatically via
  179. ** those wonderful AppleEvent thingies. */
  180.  
  181. #pragma segment Initialize
  182. void    StartDocuments(void)
  183. {
  184.     OSErr        err;
  185.     short        i;
  186.     short        whatToDo;
  187.     short        numberOfFiles;
  188.     AppFile        theAppFile;
  189.     FSSpec        fileSpec;
  190.     long        ignore;
  191.     FileRecHndl    frHndl;
  192.     WindowPtr    docWindow;
  193.     TreeObjHndl    wobj;
  194.     long        attr;
  195.  
  196.     if (gNoDefaultDocument) return;
  197.  
  198.     err = noErr;
  199.  
  200.     if (!gHasAppleEvents) {
  201.  
  202.         CountAppFiles(&whatToDo, &numberOfFiles);
  203.  
  204.         if (numberOfFiles > 0) {
  205.  
  206.             for (i = 1; (i <= numberOfFiles) && (!err); ++i) {
  207.                 GetAppFiles(i, &theAppFile);
  208.                 ClrAppFiles(i);
  209.                 err = GetWDInfo(theAppFile.vRefNum, &fileSpec.vRefNum, &fileSpec.parID, &ignore);
  210.  
  211.                 if (err)
  212.                     HCenteredAlert(rErrorAlert, nil, (ModalFilterProcPtr)AlertFilter);
  213.  
  214.                 else {
  215.                     pcpy(fileSpec.name, theAppFile.fName);
  216.                     err = OpenDocument(&frHndl, &fileSpec, fsRdWrPerm);
  217.                     if (!err) {
  218.                         gPrintPage = whatToDo;
  219.                             /* Open the window off-screen if we are printing. */
  220.                         err = DoNewWindow(frHndl, &docWindow, FrontWindow(), (WindowPtr)-1);
  221.                         if (err)
  222.                             DisposeDocument(frHndl);
  223.                         else {
  224.                             if (gPrintPage) {
  225.                                 err = PrintDocument(frHndl, (i == 1), (i == 1));
  226.                                 DisposeDocument(frHndl);
  227.                                 DisposeAnyWindow(docWindow);
  228.                             }
  229.                         }
  230.                         gPrintPage = 0;
  231.                     }
  232.                     if ((err) && (err != userCanceledErr)) {
  233.                         HCenteredAlert(rErrorAlert, nil, (ModalFilterProcPtr)AlertFilter);
  234.                         break;
  235.                     }
  236.                 }
  237.             }
  238.             if (whatToDo == appPrint)
  239.                 gQuitApplication = true;
  240.         }
  241.         else {
  242.             err = DoOpenApplication();
  243.             if (!err) {
  244.                 if (gWindowFormats) {
  245.                     for (i = (*gWindowFormats)->numChildren; i;) {
  246.                         wobj = GetChildHndl(gWindowFormats, --i);
  247.                         attr = mDerefWFMT(wobj)->attributes;
  248.                         if (!(attr & kwRuntimeOnlyDoc)) {
  249.                             if (attr & kwAutoNew) {
  250.                                 err = NewDocumentWindow(&frHndl, mDerefWFMT(wobj)->sfType, true);
  251.                                 if (err) break;
  252.                             }
  253.                         }
  254.                     }
  255.                 }
  256.                 else {
  257.                     if (!gNoDefaultDocument) {
  258.                         err = NewDocument(&frHndl, gAppWindowType, true);
  259.                         if (!err)
  260.                             if (frHndl)
  261.                                 if (err = DoNewWindow(frHndl, nil, FrontWindow(), (WindowPtr)-1))
  262.                                     DisposeDocument(frHndl);
  263.                     }
  264.                 }
  265.             }
  266.         }
  267.     }
  268.  
  269.     DonePrinting();        /* Clean up after printing, if we did any. */
  270. }
  271.  
  272.  
  273.  
  274.